/**
 * @file base_registrar.h
 * @brief 注册器基类 - 提供通用的服务注册逻辑和错误处理
 * @version 2.0
 */
#pragma once

#include "infrastructure/di/servicecontainer.h"
#include "kernel/interfaces/ILogger.h"
#include "kernel/interfaces/Result.h"
#include "../factories/service_factory.h"
#include <vector>
#include <functional>
#include <string>
#include <memory>
#include <iostream>
#include <QString>

namespace bootstrap {
namespace registrars {

using namespace infrastructure;
using namespace factories;
using kernel::Result;

// Import template functions and classes from service factory
using factories::ServiceRegistrationBuilder;
using factories::registerService;

/**
 * @brief 注册器基类 - 统一错误处理和日志记录
 */
class BaseRegistrar {
protected:
    std::shared_ptr<ServiceContainer> m_container;
    std::shared_ptr<::kernel::ILogger> m_logger;
    std::string m_registrarName;
    
    // 注册的服务信息记录
    struct ServiceRegistration {
        std::string interfaceName;
        std::string implementationName;
        ServiceConfig config;
        std::function<void()> registrationFunc;
    };
    
    std::vector<ServiceRegistration> m_registrations;

public:
    explicit BaseRegistrar(std::shared_ptr<ServiceContainer> container, 
                          const std::string& name)
        : m_container(container)
        , m_registrarName(name)
    {
        if (!m_container) {
            throw std::invalid_argument(m_registrarName + " - Container cannot be null");
        }
    }
    
    virtual ~BaseRegistrar() = default;

    /**
     * @brief 注册所有服务
     */
    virtual void registerServices() {
        try {
            // 延迟获取logger，确保基础设施已注册
            if (!m_logger) {
                m_logger = tryResolveLogger();
            }
            
            logInfo("开始注册服务...");
            
            // 调用派生类实现
            doRegisterServices();
            
            // 执行所有注册
            executeRegistrations();
            
            logInfo("服务注册完成");
        }
        catch (const std::exception& ex) {
            handleRegistrationError("服务注册失败", ex);
            throw;
        }
    }
    
    /**
     * @brief 初始化已注册的服务
     */
    virtual void initializeServices() {
        try {
            if (!m_logger) {
                m_logger = tryResolveLogger();
            }
            
            logInfo("开始初始化服务...");
            
            // 调用派生类实现
            doInitializeServices();
            
            logInfo("服务初始化完成");
        }
        catch (const std::exception& ex) {
            handleRegistrationError("服务初始化失败", ex);
            throw;
        }
    }

protected:
    /**
     * @brief 派生类实现具体的服务注册逻辑
     */
    virtual void doRegisterServices() = 0;
    
    /**
     * @brief 派生类实现具体的服务初始化逻辑
     */
    virtual void doInitializeServices() {}
    
    /**
     * @brief 添加服务注册
     */
    template<typename TInterface, typename TImplementation>
    void addRegistration(ServiceRegistrationBuilder<TInterface, TImplementation> builder) {
        const auto& config = builder.getConfig();
        
        ServiceRegistration registration;
        registration.interfaceName = typeid(TInterface).name();
        registration.implementationName = typeid(TImplementation).name();
        registration.config = config;
        registration.registrationFunc = [this, builder = std::move(builder)]() mutable {
            try {
                builder.registerTo(*m_container);
                logDebug(QString::fromStdString("已注册服务: " + std::string(typeid(TInterface).name()) + 
                        " -> " + std::string(typeid(TImplementation).name())));
            }
            catch (const std::exception& e) {
                logError(QString::fromStdString("注册服务失败: " + std::string(e.what())));
                if (builder.getConfig().required) {
                    throw;
                }
            }
        };
        
        m_registrations.push_back(std::move(registration));
    }
    
private:
    // SFINAE helper to detect if service has initialize method
    template<typename T>
    auto tryInitialize(T* service, int) -> decltype(service->initialize()) {
        return service->initialize();
    }
    
    template<typename T>
    auto tryInitialize(T* service, long) -> Result<bool> {
        // Return success for services without initialize method
        return Result<bool>::success(true);
    }

public:
    /**
     * @brief 安全初始化服务（带错误处理）
     */
    template<typename TInterface>
    bool safeInitializeService(const std::string& serviceName, bool required = true) {
        try {
            auto service = m_container->resolve<TInterface>();
            if (!service) {
                logWarning(QString::fromStdString(serviceName + " 服务解析失败"));
                if (required) {
                    throw std::runtime_error(serviceName + " 服务解析失败");
                }
                return false;
            }
            
            // 尝试调用initialize方法（如果存在）
            try {
                auto result = tryInitialize(service.get(), 0);
                if (!result.isSuccess()) {
                    logWarning(QString::fromStdString(serviceName + " 初始化失败: ") + result.getErrorMessage());
                    if (required) {
                        throw std::runtime_error(serviceName + " 初始化失败: " + result.getErrorMessage().toStdString());
                    }
                    return false;
                }
            } catch (const std::exception& initEx) {
                // 初始化失败
                logWarning(QString::fromStdString(serviceName + " 初始化异常: " + initEx.what()));
                if (required) {
                    throw;
                }
                return false;
            }
            
            logInfo(QString::fromStdString(serviceName + " 初始化成功"));
            return true;
        }
        catch (const std::exception& e) {
            logError(QString::fromStdString(serviceName + " 初始化异常: ") + e.what());
            if (required) {
                throw;
            }
            return false;
        }
    }

    /**
     * @brief 执行所有注册
     */
    void executeRegistrations() {
        int successCount = 0;
        int failureCount = 0;
        
        for (auto& registration : m_registrations) {
            try {
                registration.registrationFunc();
                successCount++;
            }
            catch (const std::exception&) {
                failureCount++;
                if (registration.config.required) {
                    throw;
                }
            }
        }
        
        logInfo(QString("注册统计: 成功 %1, 失败 %2").arg(successCount).arg(failureCount));
    }
    
    /**
     * @brief 尝试解析Logger
     */
    std::shared_ptr<::kernel::ILogger> tryResolveLogger() {
        try {
            return m_container->resolve<::kernel::ILogger>();
        }
        catch (...) {
            // Logger可能还未注册，返回nullptr
            return nullptr;
        }
    }
    
    /**
     * @brief 日志记录辅助函数
     */
    void logInfo(const QString& message) {
        if (m_logger) {
            m_logger->info(QString("[%1] %2").arg(QString::fromStdString(m_registrarName), message));
        }
    }
    
    void logWarning(const QString& message) {
        if (m_logger) {
            m_logger->warning(QString("[%1] %2").arg(QString::fromStdString(m_registrarName), message));
        }
    }
    
    void logError(const QString& message) {
        if (m_logger) {
            m_logger->error(QString("[%1] %2").arg(QString::fromStdString(m_registrarName), message));
        }
    }
    
    void logDebug(const QString& message) {
        if (m_logger) {
            m_logger->debug(QString("[%1] %2").arg(QString::fromStdString(m_registrarName), message));
        }
    }
    
    /**
     * @brief 统一错误处理
     */
    void handleRegistrationError(const QString& operation, const std::exception& ex) {
        QString errorMsg = QString("%1: %2").arg(operation, ex.what());
        
        if (m_logger) {
            m_logger->error(QString("[%1] %2").arg(QString::fromStdString(m_registrarName), errorMsg));
        } else {
            // 回退到标准错误输出
            std::cerr << "[" << m_registrarName << "] " << errorMsg.toStdString() << std::endl;
        }
    }
};

} // namespace registrars
} // namespace bootstrap